package concurrensy.sin_array_sumator;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class ConcurrentSinArraySumatorWithExecutor implements SinArraySumator {

	private class SinCounter implements Callable<Double> {

		private int counter;
		@Override
		public Double call() throws Exception {
			Double result = 0D;
			for (; counter < 0; counter++) {
				result += Math.sin(counter);
				result += Math.sin(-counter);
			}
			return result;
		}
		
		public SinCounter(int counter){
			this.counter = counter;
		}
	}

	private static final int DEFAULT_ONE_THREAD_VALUE = 3600;
	private volatile double result;
	
	ExecutorService fixedThreadPool;
	@Override
	public double arraySum(int parameter) {
		int threadCount = parameter/DEFAULT_ONE_THREAD_VALUE;
		int restValue = parameter%DEFAULT_ONE_THREAD_VALUE;
		fixedThreadPool = Executors.newFixedThreadPool(threadCount + 1);
		
		for(int count = 0; count <= threadCount; count++){
			Future<Double> submitResult = fixedThreadPool.submit(new SinCounter(DEFAULT_ONE_THREAD_VALUE));
			increaseResult(submitResult);
		}
		
		Future<Double> submitResult = fixedThreadPool.submit(new SinCounter(restValue));
		increaseResult(submitResult);
		return result;
	}
	private void increaseResult(Future<Double> submitResult) {
		try {
			result += submitResult.get();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
	}

}
